package fina2.dcs.metadata;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Remove;
import javax.ejb.Stateful;
import javax.faces.context.FacesContext;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;

import org.jboss.annotation.ejb.LocalBinding;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.Destroy;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.log.Log;

import fina2.dcs.common.UIComponentHelper;
import fina2.dcs.i18n.LanguageSession;
import fina2.dcs.system.SysString;
import fina2.dcs.system.SysStringLocal;
import fina2.dcs.system.SysStringPk;

@Stateful
@Name("periodTypeSession")
@Scope(ScopeType.SESSION)
@LocalBinding(jndiBinding = "PeriodTypeSession/local")
@SuppressWarnings("unchecked")
@AutoCreate
public class PeriodTypeSession implements PeriodTypeLocal,Serializable {
	@PersistenceContext
	private EntityManager em;

	private List<PeriodType> periodTypes = new ArrayList<PeriodType>();

	private PeriodType periodType = new PeriodType();

	@EJB
	private SysStringLocal sysStringLocal;

	private String code = null;

	private String description = null;

	private PeriodType selectedPerType = new PeriodType();

	private boolean success = false;

	private final BigDecimal defaultIndex = new BigDecimal("1");
	
	@Logger
	private Log log;
	
	public void init() {
		log.info("Initializing Period Types...");
		try {
			

			periodTypes = em.createQuery("FROM " + PeriodType.class.getName() + " p ORDER BY p.code ASC").getResultList();

			List<BigDecimal> periodTypesNameStrid = new ArrayList<BigDecimal>();
			for (int i = 0; i < periodTypes.size(); i++) {
				periodTypesNameStrid.add(periodTypes.get(i).getNameStrId());
			}

			StringBuffer sb = new StringBuffer(periodTypesNameStrid.toString());
			sb.replace(0, 1, "");
			sb.replace(sb.toString().length() - 1, sb.toString().length(), "");

			List<SysString> descriptions = sysStringLocal.getAllValues(sb.toString(), LanguageSession.langId);

			for (int i = 0; i < periodTypes.size(); i++) {
				for (int j = 0; j < descriptions.size(); j++)
					if (periodTypes.get(i).getNameStrId().equals(descriptions.get(j).getPk().getId())) {
						periodTypes.get(i).setDescription(descriptions.get(j).getValue());
						break;
					}
			}

		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
		}
	}

	public String addPeriodType() {
		try {
			periodType.setId(getMaxId().add(defaultIndex));
			periodType.setNameStrId(sysStringLocal.getMaxId().add(defaultIndex));
			em.persist(periodType);

			BigDecimal id = sysStringLocal.getMaxId().add(defaultIndex);

			SysStringPk pk = new SysStringPk();
			pk.setId(id);
			pk.setLangId(LanguageSession.langId);
			SysString ss = new SysString();
			ss.setPk(pk);
			ss.setValue(periodType.getDescription());
			sysStringLocal.addString(ss);

			success = true;
		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
		} finally {
			periodType = new PeriodType();
		}
		return "periodTypeAdded";
	}

	public String updatePeriodType() {
		log.info("Updating Period Type");
		try {
			PeriodType pr = em.find(PeriodType.class, selectedPerType.getId());
			pr.setCode(selectedPerType.getCode());
			BigDecimal id = pr.getNameStrId();
			em.merge(pr);

			SysStringPk pk = new SysStringPk(id, LanguageSession.langId);
			SysString ss = sysStringLocal.findByPk(pk);
			ss.setValue(description);
			sysStringLocal.updateString(ss);

			success = true;
		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
		} finally {
			selectedPerType = new PeriodType();
			description = null;
		}
		return "periodTypeUpdated";
	}

	public void removePeriodType() {
		log.info("Removing Period Type " + code);
		try {
			PeriodType pt = findByCode(code);
			BigDecimal id = pt.getNameStrId();
			em.remove(pt);

			SysStringPk pk = new SysStringPk(id, LanguageSession.langId);
			sysStringLocal.removeString(pk);

			success = true;
		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
		}

	}

	public PeriodType findByCode(String code) {
		PeriodType pt = null;
		try {
			pt = (PeriodType) em.createQuery("FROM " + PeriodType.class.getName() + " p WHERE RTRIM(p.code)=?").setParameter(1, code.trim()).getSingleResult();
		} catch (NoResultException ex) {
			pt = null;
		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
		}
		return pt;
	}

	@Remove
	@Destroy
	public void remove() {

	}

	public PeriodType getPeriodType() {
		return periodType;
	}

	public void setPeriodType(PeriodType periodType) {
		this.periodType = periodType;
	}

	public List<PeriodType> getPeriodTypes() {
		return periodTypes;
	}

	public void setPeriodTypes(List<PeriodType> periodTypes) {
		this.periodTypes = periodTypes;
	}

	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}

	@Override
	public BigDecimal getMaxId() {
		BigDecimal maxId = new BigDecimal("0");
		try {
			maxId = (BigDecimal) em.createQuery("SELECT MAX(id) FROM " + PeriodType.class.getName() + " p").getSingleResult();
			if (maxId == null)
				maxId = defaultIndex;
		} catch (NoResultException ex) {
			maxId = defaultIndex;
		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
		}
		return maxId;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public boolean isSuccess() {
		return success;
	}

	public void setSuccess(boolean success) {
		this.success = success;
	}

	public PeriodType getSelectedPerType() {
		return selectedPerType;
	}

	public void setSelectedPerType(PeriodType selectedPerType) {
		UIComponentHelper.clearComponent(FacesContext.getCurrentInstance().getViewRoot());
		this.selectedPerType = selectedPerType;
		description = selectedPerType.getDescription();
		success = false;
	}

}